<!DOCTYPE html>
<html lang="en">
  
  <head>
    <meta charset="UTF-8">
    <title>节点的动画</title>
  </head>
  
  <body>
    <div id="mountNode"></div>
    <script src="../build/g6.js"></script>
    <script>
      const Util = G6.Util;
      const data = {
        nodes: [{
          id: 'node1',
          x: 100,
          y: 100,
          shape: 'circle-animate',
          size: 20,
          label: '图形动画',
          labelCfg: {
            position: 'bottom'
          }
        },
        {
          id: 'node2',
          x: 300,
          y: 200,
          shape: 'background-animate',
          color: '#b5b5b5',
          size: 20,
          label: '背景动画',
          labelCfg: {
            position: 'bottom'
          }
        },
        {
          id: 'node3',
          x: 400,
          y: 100,
          size: [40, 40],
          shape: 'inner-animate',
          img: '',
          label: 'rect',
          labelCfg: {
            position: 'bottom'
          }
        },
        {
          id: 'node4',
          x: 300,
          y: 400,
          shape: 'rect',
          label: 'rect',
          labelCfg: {
            position: 'bottom'
          }
        }],
        edges: [{
          source: 'node1',
          target: 'node2'
        },
        {
          source: 'node3',
          target: 'node2'
        },
        {
          source: 'node2',
          target: 'node4'
        }]
      };

      // 放大、变小动画
      G6.registerNode('circle-animate', {
        afterDraw(cfg, group) {
          const shape = group.get('children')[0];
          shape.animate({
            repeat: true,
            onFrame(ratio) {
              const diff = ratio <= 0.5 ? ratio * 10 : (1 - ratio) * 10;
              return {
                r: cfg.size / 2 + diff
              }
            }
          },
          3000, 'easeCubic');
        }
      },
      'circle');

      G6.registerNode('background-animate', {
        afterDraw(cfg, group) {
          const r = cfg.size / 2;
          const back1 = group.addShape('circle', {
            zIndex: -3,
            attrs: {
              x: 0,
              y: 0,
              r,
              fill: cfg.color,
              opacity: 0.6
            }
          });
          const back2 = group.addShape('circle', {
            zIndex: -2,
            attrs: {
              x: 0,
              y: 0,
              r,
              fill: cfg.color,
              // 为了显示清晰，随意设置了颜色
              opacity: 0.6
            }
          });

          const back3 = group.addShape('circle', {
            zIndex: -1,
            attrs: {
              x: 0,
              y: 0,
              r,
              fill: cfg.color,
              opacity: 0.6
            }
          });
          group.sort(); // 排序，根据zIndex 排序
          back1.animate({ // 逐渐放大，并消失
            r: r + 10,
            opacity: 0.1,
            repeat: true // 循环
          },
          3000, 'easeCubic', null, 0) // 无延迟
          back2.animate({ // 逐渐放大，并消失
            r: r + 10,
            opacity: 0.1,
            repeat: true // 循环
          },
          3000, 'easeCubic', null, 1000) // 1 秒延迟
          back3.animate({ // 逐渐放大，并消失
            r: r + 10,
            opacity: 0.1,
            repeat: true // 循环
          },
          3000, 'easeCubic', null, 2000) // 2 秒延迟
        }
      },
      'circle');

      G6.registerNode('inner-animate', {
        afterDraw(cfg, group) {
          const size = cfg.size;
          const width = size[0] - 12;
          const height = size[1] - 12;
          const image = group.addShape('image', {
            attrs: {
              x: -width / 2,
              y: -height / 2,
              width: width,
              height: height,
              img: cfg.img
            }
          });
          image.animate({
            onFrame(ratio) {
              const matrix = Util.mat3.create();
              const toMatrix = Util.transform(matrix, [['r', ratio * Math.PI * 2]]);
              return {
                matrix: toMatrix
              };
            },
            repeat: true
          },
          3000, 'easeCubic');
        }
      },
      'rect');

      const graph = new G6.Graph({
        container: 'mountNode',
        width: 1000,
        height: 600
      });
      graph.data(data);
      graph.render();
    </script>
  </body>

</html>